<?php

namespace App\HttpController\Api;

use App\Model\GameLog as GameLogModel;
use App\Model\Trade as TradeModel;
use App\Think\Cache;
use App\Think\Db;

/**
 * 游戏接口Game
 */
class Game extends ApiBase
{
    protected $noNeedLogin = ['sync_log','game_list'];

    /**
     * 游戏记录查询
     * @param string $starttime 开始时间|格式20200101
     * @param string $endtime   结束时间|格式20200101
     * @param string $platform  游戏平台|可选|Datang=大唐游戏,查看全部记录传空字符串
     * @param string $status  状态值|可选|:0=未结算,1=已结算,2=已拒绝,3=取消/退回,查看全部记录传空字符串
     * @param string $page  当前页数
     */
    public function game_log(){
        $page      = (int)$this->input("page");
        $platform  = $this->input("platform");
        $status    = $this->input("status");
        $starttime = $this->input("starttime");
        $endtime = $this->input("endtime");
        if(!$starttime || !$endtime) return $this->error(__('请求参数不完整'));
        if($page <= 0) $page = 1;

        $where = " createtime between ".strtotime($starttime." 00:00:00")." AND ".strtotime($endtime." 23:59:59");
        $where .= " AND user_id='{$this->auth->id}' ";
        if($status != '') $where .= " AND status='{$status}' ";
        if($platform != '')   $where .= " AND plat_key='{$platform}' ";
        $res = GameLogModel::log_list($where,$page);
        $list = [];
        //数据处理
        foreach ($res as $k => $v) {
            $list[$k] = $v;
            $list[$k]['icon'] = '';
        }
        $res = Db::query("SELECT count(1) row,SUM(money_valid) flow,SUM(money_winlose) winlose FROM ".Db::getTable('game_log')." WHERE 1 AND {$where}");
        $total = $res[0];
        return $this->success(__('success'), ['list'=>$list, 'total'=>[ 'row'=>(int)$total['row'], 'flow'=>(float)$total['flow'], 'winlose'=>(float)$total['winlose'] ] ] );
    }

    /**
     * 游戏记录同步
     * ApiMethod (POST)
     * @param string $platform 游戏平台|Datang=大唐游戏...
     * @param string $startTime 开始时间|格式如20180429&nbsp;10:00:00
     * @param string $endTime   结束时间|格式如20180429&nbsp;20:00:00
     * @param string $page      第几页|默认1,可选
     * @param string $limit     页大小|不能大于1000默认100,可选
     */
    public function sync_log(){
        $platform = $this->input("platform");
        $startTime = $this->input("startTime");
        $endTime   = $this->input("endTime");

        if( check_platform_status($platform) == false ) return $this->error(__('该平台正在维护,请稍后再试...'));
        $user = $this->auth->getUser();
        
        // $res = \app\common\library\Game::instance()->sync_log(['platform'=>$platform, 'startTime'=>$startTime, 'endTime'=>$endTime, 'account'=>$user->username]);
        $GameLogModel = new \app\common\model\GameLog();
        $res = $GameLogModel->sync_log(['platform'=>$platform, 'startTime'=>$startTime, 'endTime'=>$endTime, 'account'=>$user->username]);
        
        if($res['api_call'] == false) return $this->error(__("{$platform}同步接口调用失败"));
        return $this->success(__('success'), $res);
    }

    /**
     * 登录(进入)游戏
     * @param string $platform 游戏平台|Datang=大唐游戏...
     * @param string $device   设备|mobile=手机端|默认,pc=电脑端
     * @param string $game_id  游戏ID|可选
     */
    public function login(){
        $platform = $this->input("platform");
        $device   = $this->input("device");
        $game_id  = $this->input("game_id");
        if(!$device) $device = 'mobile';
        if( check_platform_status($platform) == false ) return $this->error(__('该平台正在维护,请稍后再试...'));
        //请求限制
        $cache_key = "gameLogin:{$this->auth->id}:{$platform}:{$device}:{$game_id}";
        $res = cache($cache_key);
        if(!$res){
            // $user = $this->auth->getUser();
            $req_param = [
                'account' => $this->auth->username,
                'device'  => $device,
                'game_id' => $game_id,
                'usertoken'   => $this->auth->getToken(),
            ];
            $cls_name = '\gamesdk\\'.$platform;
            $cls      = new $cls_name();

            //未注册：注册
            $this->_register($platform,$this->auth->id,$this->auth->username,$device);
            //已注册：登录
            $res = $cls->login($req_param);
            //不同平台限制不同
            $cacheTime = in_array($platform, ['AGZR']) ? 5 : 120;
            cache($cache_key, $res, $cacheTime);
        }
        
        if($res['code'] <= 0) return $this->error(__("登录失败({$res['code']}),请联系管理员"), $res);
        return $this->success(__('success'), $res);
    }
    /**
     * 游戏列表(第三方)
     * @param string $platform 游戏平台|SEA=SEA电子...
     */
    public function game_list(){
        $platform = $this->input("platform");
        if( check_platform_status($platform) == false ) return $this->error(__('该平台正在维护,请稍后再试...'));

        $req_param = $res = [];
        $cls_name = '\gamesdk\\'.$platform;
        $cls      = new $cls_name();
        if(method_exists($cls,'gameList')) $res = $cls->gameList($req_param);
        // if($res['code'] <= 0) return $this->error(__("登录失败({$res['code']}),请联系管理员"), $res);
        return $this->success(__('success'), ['list'=>$res]);
    }
    /**
     * 账号信息(第三方)废弃!
     * @param string $platform 游戏平台|Datang=大唐游戏...
     */
    public function account_info(){
        $platform = $this->input("platform");
        if( check_platform_status($platform) == false ) return $this->error(__('该平台正在维护,请稍后再试...'));

        $req_param = [
            'account' => $this->auth->username
        ];
        $cls_name = '\gamesdk\\'.$platform;
        $cls      = new $cls_name();
        $res = $cls->userInfo($req_param);
        if($res['code'] <= 0) return $this->error(__("请求失败({$res['code']})"), $res);
        return $this->success(__('success'), $res);
    }

    /**
     * 余额查询(第三方)
     * @param string $platform 游戏平台|Datang=大唐游戏...
     */
    public function balance(){
        $platform = $this->input("platform");
        if( check_platform_status($platform) == false ) return $this->error(__('该平台正在维护,请稍后再试...'));
        //余额缓存
        $cache_key = "balance:{$platform}:{$this->auth->id}";
        $res = cache($cache_key);
        if(!$res){
            $req_param = [ 'account' => $this->auth->username ];
            $cls_name = '\gamesdk\\'.$platform;
            $cls      = new $cls_name();
            $res = @$cls->balance($req_param);
            cache($cache_key, $res, 60);
        }
        // if($res['code'] <= 0) return $this->error(__("请求失败({$res['code']})"), $res);
        $json = ['code'=>1, 'balance'=>(float)sprintf("%.2f",@$res['balance'])];
        return $this->success(__('success'), $res);
    }
    /**
     * 余额转账(上下分)
     * ApiMethod (POST)
     * @param string $platform  平台|大唐游戏=Datang,其他...
     * @param string $type     类型|转入/上分=upper,转出/下分=lower
     * @param string $money    金额|转出所有=all
     */
    public function transfer()
    {
        $platform = $this->input("platform");
        $type     = $this->input("type");
        $money    = $this->input("money");
        if(!$platform || !$type ) return $this->error(__('请求参数不完整'));
        // if( ($from != 'wallet' && $to != 'wallet') || ($from == 'wallet' && $to == 'wallet') ) return $this->error(__('请选择其中一方为中心钱包'));
        if( check_platform_status($platform) == false ) return $this->error(__('该平台正在维护,请稍后再试...'));
        if(!in_array($type, ['upper','lower'])) return $this->error(__('请选择转入或转出'));
        if($money != 'all' && $money<=0) return $this->error(__('金额请输入整数'));

        //请求限制
        $cache_key = "transfer:{$this->auth->id}:{$platform}:{$type}";
        $cache_val = cache($cache_key);
        if($cache_val) return $this->error(__('请求太频繁，请5秒后再试'));
        if(empty($cache_val)) cache($cache_key, time(), 5);

        //未注册：注册
        $this->_register($platform,$this->auth->id,$this->auth->username, 'mobile');

        $param = $this->request->param();
        $param['user_id'] = $user_id = $this->auth->id;
        $param['status'] = 1;
        $param['order_sn'] = $orderid = order_sn();
        //亚博棋牌特殊处理
        if($platform == 'YBQP') $param['order_sn'] = $orderid = time()*1000+rand(100,999);

        //中心钱包=>游戏平台(上分)
        if($type == 'upper'){
            if($money > $this->auth->money) return $this->error(__('余额不足,请先充值'));
            list($param['from'], $param['to'], $param['money']) = ['wallet', $platform, -$money];
            $param['memo'] = '转入['.platform_name($platform)."]:{$money}元";
            //调用第三方转入到游戏(todo)...
            $cls_name = '\gamesdk\\'.$platform;
            $cls      = new $cls_name();
            $req_param = [
                'account' => $this->auth->username,
                'orderid' => $orderid,
                'money'   => $money
            ];
            $res = $cls->transIn($req_param);
            if($res['code'] <= 0) return $this->error(__("转入失败({$res['code']}),请联系管理员"), $res);
        }
        //游戏平台=>中心钱包(下分)
        if($type == 'lower'){
            list($param['from'], $param['to'], $money) = [$platform, 'wallet', $money];
            $cls_name = '\gamesdk\\'.$platform;
            $cls      = new $cls_name();

            //获取所有余额
            if($money == 'all'){
                // $money = (float)cache("balance:{$platform}:{$this->auth->id}");
                // if(!$money){
                    $res_balance = @$cls->balance([ 'account' => $this->auth->username ]);
                    $money = (float)@$res_balance['balance'];
                // }
                $param['money'] = $money;
            }
            if($money <= 0) return $this->success(__('转账成功'));
            //调用转出API
            $param['memo'] = '转出['.platform_name($platform)."]:{$money}元";
            $req_param = [
                'account' => $this->auth->username,
                'orderid' => $orderid,
                'money'   => (string)$money
            ];
            $res = $cls->transOut($req_param);
            if($res['code'] <= 0) return $this->error(__("转出失败({$res['code']}),请联系管理员"), $res);
        }
            
        //更新余额缓存
        $cache_key = "balance:$platform:{$this->auth->id}";
        cache($cache_key, NULL);
        cache("userIndex:{$user_id}", NULL);

        $res = TradeModel::transfer($param);
        if(!$res) return $this->error(__('无法写入数据,转账失败'));
        return $this->success(__('转账成功'), $res);
    }
    /**
     * 一键回收
     * ApiMethod (POST)
     */
    public function recovery(){
        //请求限制
        $cache_key = "recovery:{$this->auth->id}";
        if(cache($cache_key)) return $this->error(__('请求太频繁，请15秒后再试'));
        if(empty($cache_val)) cache($cache_key, time(), 15);

        $plat_list = platform_list();
        $arr = [];
        $total_money = $money = 0;
        foreach ($plat_list as $k => $v) {
            $platform = $v['key'];
            $cache_key = "balance:{$platform}:{$this->auth->id}";
            if(cache($cache_key)<=0) continue;

            $cls = $res = $cls_name = null;
            $cls_name = '\gamesdk\\'.$platform;
            $cls      = new $cls_name();
            //生成订单号
            $orderid = order_sn();
            if($platform == 'YBQP') $orderid = time()*1000+rand(0,999); //亚博棋牌特殊处理
            //获取平台余额
            $res = @$cls->balance([ 'account' => $this->auth->username ]);
            $money = (float)@$res['balance'];

            if($money > 0){
                $req_param = [
                    'account' => $this->auth->username,
                    'orderid' => $orderid,
                    'money'   => $money
                ];
                $res_trans = $cls->transOut($req_param);
                if($res_trans['code'] == 1){
                    $total_money = $total_money+$money;
                    $arr[] = ['plat_key'=>$platform, 'money'=>$money];
                    //清空余额缓存
                    cache($cache_key, NULL);
                } 
            }
        }

        if($total_money > 0) TradeModel::transfer(['user_id'=>$this->auth->id,'from'=>'','to'=>'wallet','money'=>$total_money,'status'=>1,'memo'=>'一键会收']);
        return $this->success(__('回收成功'), ['list'=>$arr, 'total_money'=>$total_money]);
    }



    //判断是否注册
    private function _register($platform,$user_id,$username,$device){
        //未注册：注册
        $game_account = db_get_field('game_account', "user_id='{$user_id}' AND plat_key='{$platform}'", 'account');
        if(empty($game_account)){
            $req_param = [
                'account' => $username,
                'device'  => $device,
                // 'game_id' => $game_id,
                // 'usertoken'   => $this->auth->getToken(),
            ];
            $cls_name = '\gamesdk\\'.$platform;
            $cls      = new $cls_name();
            $cls->register($req_param);
            db_add('game_account', ['user_id'=>$user_id, 'plat_key'=>$platform, 'account'=>$username, 'createtime'=>time()]);
        }
        return true;
    }

}
